<template>
  <div>
    <div id="gid_tc" style="float:left;">
      <div id="gid"></div>
      <ul
        class="el-dropdown-menu el-popper"
        id="my_custom_menu"
        style="display: none;"
      >
        <li class="el-dropdown-menu__item" @click="btnOpenNode">
          <svg class="ctwh_icon" aria-hidden="true">
            <use xlink:href="#icon-zk-all"></use>
          </svg>
          <span class="pl-15">展开</span>
        </li>
        <li class="el-dropdown-menu__item" @click="btnCollapseNode">
          <svg class="ctwh_icon" aria-hidden="true">
            <use xlink:href="#icon-shouqi"></use>
          </svg>
          <span class="pl-15">收起</span>
        </li>
      </ul>
      <div
        class="el-dropdown-menu el-popper"
        id="richContainer"
        style="display: none;width: 420px;height: 300px;position: absolute; left: 222px; top: 75px;"
      >
        <span
          @click="close"
          class="close-x"
          style="
                float: right;
                padding: 4px 8px;
                cursor: pointer;
                color: rgb(236, 105, 65);font-size: 16px;margin: -20px -33px 0 0;background: #fff;border-radius: 50%;border: 1px solid #ddd;z-index: 999;font-family: '微软雅黑';"
          >X</span
        >
        <div class="search_result_list_min">
          <div
            :key="'m_' + index"
            v-for="(item, index) in nodeRecordList"
            class="search_result_item_min"
          >
            <div>
              <div class="datatitle">
                <a href="javascript:;" @click="linkto(item)"
                  >{{ index + 1 }}.{{ item.条目名称 }}
                </a>
              </div>
              <div class="datasource">
                <span>{{ item.工具书名称 }}</span>
              </div>
            </div>
            <span class="datacontent" @click="linkto(item)" v-html="item.快照">
              {{ item.快照 }}
            </span>
          </div>
        </div>
      </div>
      <div class="mengceng"></div>
    </div>
    <div class="svg-set-box clearfix">
      <div class="ctwh-dibmr">
        <span>显示范围：</span>
        <a
          :key="index"
          v-for="(m, index) in pageSizeList"
          @click="setMatchSize(m, this)"
          href="javascript:void(0)"
          :class="[m.isActive ? 'sd-active' : '', 'ss-d sd' + (index + 1)]"
        >
        </a>
      </div>
      <div class="ctwh-dibmr" style="float: right">
        <ul class="toolbar">
          <li>
            <a href="javascript:;" @click="zoomin"
              ><span><i class="el-icon-zoom-in"></i>放大</span></a
            >
          </li>
          <li>
            <a href="javascript:;" @click="zoomout"
              ><span><i class="el-icon-zoom-out"></i>缩小</span></a
            >
          </li>
          <li>
            <a href="javascript:;" @click="refresh"
              ><span><i class="el-icon-refresh-right"></i>还原</span></a
            >
          </li>
          <li>
            <a
              v-if="!isFullscreen"
              id="fullscreenbtn"
              href="javascript:;"
              @click="showFull"
            >
              <span><i class="el-icon-full-screen"></i>全屏</span>
            </a>
            <a
              v-else
              id="fullscreenbtn"
              href="javascript:;"
              @click="exitfullscreen"
            >
              <span><i class="el-icon-full-screen"></i>退出全屏</span>
            </a>
          </li>
        </ul>
      </div>
    </div>
  </div>
</template>
<script>
import axios from "axios";
import * as d3 from "d3";
import $ from "jquery";

export default {
  props: ["pid"],
  data() {
    return {
      qaGraphNode: {},
      qaGraphNodeText: {},
      qaGraphLink: {},
      qaGraphLinkText: {},
      theme: 0,
      loading: false,
      width: 1000,
      height: 800,
      gcontainer: {},
      svg: {},
      zoom: null,
      arrowMarker: {},
      simulation: {},
      isFullscreen: false,
      graph: {
        nodes: [],
        links: []
      },
      colorList: [
        "#ff8373",
        "#f9c62c",
        "#a5ca34",
        "#6fce7a",
        "#70d3bd",
        "#ea91b0"
      ],
      pageSizeList: [
        { size: 100, isActive: false },
        { size: 300, isActive: false },
        { size: 500, isActive: true },
        { size: 1000, isActive: false }
      ],
      nodeRecordList: []
    };
  },
  components: {},
  mounted() {
    this.initGraphContainer();
    this.addMaker();
    this.initGraph();
  },
  created() {},
  watch: {},
  methods: {
    initGraphContainer() {
      this.gcontainer = d3.select("#gid");
      if (this.isFullscreen) {
        this.width = window.screen.width;
        this.height = window.screen.height;
      } else {
        this.width = $("#" + this.pid).width();
        this.height = $("#" + this.pid).height();
      }
      this.svg = this.gcontainer.append("svg");
      var sWidth = this.width;
      var sHeight = this.height;
      this.svg.attr("width", sWidth);
      this.svg.attr("height", sHeight);
      // this.svg.attr("viewBox", "0 0 " + sWidth / 2 + " " + sHeight / 2);
      this.svg.attr("id", "svg_idx");
      this.svg.attr("preserveAspectRatio", "xMidYMidmeet");
      this.simulation = d3
        .forceSimulation()
        .force("charge", d3.forceManyBody().strength(-1500))
        .force(
          "link",
          d3
            .forceLink()
            .distance(60)
            .id(function(d) {
              return d.uuid;
            })
        )
        .force("collide", d3.forceCollide().strength(-30))
        .force("center", d3.forceCenter(this.width / 2, this.height / 2));
      this.qaGraphLink = this.svg.append("g").attr("class", "line");
      this.qaGraphLinkText = this.svg.append("g").attr("class", "lineText");
      this.qaGraphNode = this.svg.append("g").attr("class", "node");
      this.qaGraphNodeText = this.svg.append("g").attr("class", "nodeText");
    },
    initGraph() {
      var _this = this;
      axios.get("/static/kgData.json", {}).then(function(response) {
        var data = response.data;
        _this.graph.nodes = data.node;
        _this.graph.links = data.relationship;
        _this.updateGraph();
      });
    },
    addMaker() {
      var arrowMarker = this.svg
        .append("marker")
        .attr("id", "arrow")
        .attr("markerUnits", "strokeWidth")
        .attr("markerWidth", "12") //
        .attr("markerHeight", "12")
        .attr("viewBox", "0 0 12 12")
        .attr("refX", "30")
        .attr("refY", "6")
        .attr("orient", "auto");
      var arrowPath = "M2,2 L10,6 L2,10 L6,6 L2,2"; // 定义箭头形状
      arrowMarker
        .append("path")
        .attr("d", arrowPath)
        .attr("fill", "#ccc");
    },
    drawnode(node) {
      var _this = this;
      var nodeEnter = node.enter().append("circle");
      nodeEnter.on("click", function(d) {
        console.log("触发单击:" + d);

        // eslint-disable-next-line no-debugger
        debugger;
        _this.opennode();
        console.log("ddd");
        //
      });
      nodeEnter.on("dblclick", function(d) {
        event.preventDefault();
        console.log("触发双击:" + d);
      });
      nodeEnter.call(
        d3
          .drag()
          .on("start", _this.dragstarted)
          .on("drag", _this.dragged)
          .on("end", _this.dragended)
      );
      return nodeEnter;
    },
    opennode() {
      var _this = this;
      var noddd = [
        {
          flag: "1",
          code: "27301",
          parentCode: "273",
          grade: "2",
          name: "儒家2",
          uuid: "4617858011"
        },
        {
          code: "2730107",
          flag: "1",
          parentCode: "27301",
          grade: "3",
          name: "故事轶闻2",
          uuid: "2636501111"
        }
      ];
      var newships = [
        {
          sourceid: "46178580",
          targetid: "2636501111",
          name: "",
          targetcode: "2730107",
          uuid: "91804213",
          sourcecode: "27301"
        },
        {
          sourceid: "46178580",
          targetid: "4617858011",
          name: "",
          targetcode: "273010723",
          uuid: "91804389",
          sourcecode: "2730107"
        }
      ];
      _this.graph.nodes = _this.graph.nodes.concat(noddd);
      _this.graph.links = _this.graph.links.concat(newships);
      _this.updateGraph();
    },
    drawNodeText(nodeText) {
      var _this = this;
      var nodeTextEnter = nodeText.enter().append("text");
      nodeTextEnter.call(
        d3
          .drag()
          .on("start", _this.dragstarted)
          .on("drag", _this.dragged)
          .on("end", _this.dragended)
      );
      return nodeTextEnter;
    },
    drawLink(link) {
      var _this = this;
      var linkEnter = link
        .enter()
        .append("line")
        .attr("stroke-width", 1)
        .attr("stroke", function() {
          return _this.colorList[2];
        })
        .attr("marker-end", "url(#arrow)"); // 箭头
      return linkEnter;
    },
    drawLinkText(linktext) {
      var linkTextEnter = linktext
        .enter()
        .append("text")
        .attr("class", "lineText")
        .style("fill", "#875034")
        .style("font-size", "16px")
        .text(function(d) {
          return d.lk.name;
        });
      return linkTextEnter;
    },
    updateGraph() {
      var _this = this;
      var lks = _this.graph.links;
      var nodes = _this.graph.nodes;
      nodes.forEach(function(n) {
        if (n.center === 1 || n.center === "1") {
          n.fx = _this.width / 2;
          n.fy = _this.height / 2;
        }
        if (typeof n.fx === "undefined" || n.fx === "") {
          n.fx = null;
        }
        if (typeof n.fy === "undefined" || n.fy === "") {
          n.fy = null;
        }
      });
      var links = [];
      // eslint-disable-next-line no-debugger
      debugger;
      lks.forEach(function(m) {
        var sourceNode = nodes.filter(function(n) {
          return n.uuid === m.sourceid;
        })[0];
        if (typeof sourceNode === "undefined") return;
        var targetNode = nodes.filter(function(n) {
          return n.uuid === m.targetid;
        })[0];
        if (typeof targetNode === "undefined") return;
        links.push({ source: sourceNode.uuid, target: targetNode.uuid, lk: m });
      });
      // 更新节点
      //_this.qaGraphNode = _this.drawnode(nodes);
      var node = _this.qaGraphNode.selectAll("circle").data(nodes, function(d) {
        return d.uuid;
      });
      node.exit().remove();
      var nodeEnter = _this.drawnode(node);
      node = nodeEnter.merge(node).text(function(d) {
        return d.name;
      });
      node.attr("r", 25);
      node.attr("fill", "red");
      node
        .append("title") // 为每个节点设置title
        .text(function(d) {
          return d.name;
        });
      // 更新节点文字
      //_this.qaGraphNodeText = _this.drawNodeText(nodes);
      var nodeText = _this.qaGraphNodeText
        .selectAll("text")
        .data(nodes, function(d) {
          return d.uuid;
        });
      nodeText.exit().remove();
      var nodeTextEnter = _this.drawNodeText(nodeText);
      nodeText = nodeTextEnter.merge(nodeText).text(function(d) {
        return d.name;
      });
      nodeText
        .style("fill", function() {
          if (_this.theme === 0) {
            return "#333";
          } else {
            return "#fff";
          }
        })
        .attr("class", "nodeText")
        .attr("dy", "3.6em")
        .attr("font-family", "宋体")
        .attr("font-size", 16)
        .attr("text-anchor", "middle")
        .text(function(d) {
          return d.name;
        });
      nodeText
        .append("title") // 为每个节点设置title
        .text(function(d) {
          if (typeof d.name !== "undefined") {
            return d.name;
          }
          return "";
        });
      // 更新连线 links
      // _this.qaGraphLink = _this.drawLink(links);
      var link = _this.qaGraphLink.selectAll("line").data(links, function(d) {
        return d.uuid;
      });
      link.exit().remove();
      var linkEnter = _this.drawLink(link);
      link = linkEnter.merge(link);
      // 更新连线文字
      //_this.qaGraphLinkText = _this.drawLinkText(links);
      var linktext = _this.qaGraphLinkText
        .selectAll("text")
        .data(links, function(d) {
          return d.uuid;
        });
      linktext.exit().remove();
      var linkTextEnter = _this.drawLinkText(linktext);
      linktext = linkTextEnter.merge(linktext).text(function(d) {
        return d.lk.name;
      });
      _this.simulation
        .nodes(nodes)
        .alphaTarget(0)
        .alphaDecay(0.05)
        .on("tick", ticked);
      function ticked() {
        // 更新连线坐标
        link
          .attr("x1", function(d) {
            return d.source.x;
          })
          .attr("y1", function(d) {
            return d.source.y;
          })
          .attr("x2", function(d) {
            return d.target.x;
          })
          .attr("y2", function(d) {
            return d.target.y;
          });
        // 刷新连接线上的文字位置
        linktext
          .attr("x", function(d) {
            if (
              typeof d.source.x === "undefined" ||
              typeof d.target.x === "undefined"
            )
              return 0;
            var x = (parseFloat(d.source.x) + parseFloat(d.target.x)) / 2;
            return x;
          })
          .attr("y", function(d) {
            if (
              typeof d.source.y === "undefined" ||
              typeof d.target.y === "undefined"
            )
              return 0;
            var y = (parseFloat(d.source.y) + parseFloat(d.target.y)) / 2;
            return y;
          });
        // 更新节点坐标
        node
          .attr("cx", function(d) {
            return d.x;
          })
          .attr("cy", function(d) {
            return d.y;
          });
        // 更新文字坐标
        nodeText
          .attr("x", function(d) {
            return d.x;
          })
          .attr("y", function(d) {
            return d.y;
          });
      }

      _this.simulation.force("link").links(links);
      _this.simulation.force(
        "center",
        d3.forceCenter(_this.width / 2, _this.height / 2)
      );
      _this.simulation.alpha(1).restart();
      // 鼠标滚轮缩放
      _this.zoom = d3
        .zoom()
        .scaleExtent([0.1, 4])
        .on("zoom", _this.zoomed);
      _this.svg.call(_this.zoom);
      _this.svg.on("dblclick.zoom", null); // 静止双击缩放
    },
    dragstarted(d) {
      if (!d3.event.active) this.simulation.alphaTarget(0.3).restart();
      d.fx = d.x;
      d.fy = d.y;
    },
    dragged(d) {
      d.fx = d3.event.x;
      d.fy = d3.event.y;
    },
    dragended(d) {
      if (!d3.event.active) this.simulation.alphaTarget(0);
      d.fx = d3.event.x;
      d.fy = d3.event.y;
    },
    zoomed() {
      this.svg.selectAll("g").attr("transform", d3.event.transform);
    },
    zoomClick(direction) {
      var self = this;
      var factor = 0.2;
      var targetZoom = 1;
      var extent = self.zoom.scaleExtent();
      targetZoom = 1 + factor * direction;
      if (targetZoom < extent[0] || targetZoom > extent[1]) {
        return false;
      }
      self.zoom.scaleBy(self.svg, targetZoom); // 执行该方法后 会触发zoom事件
    },
    zoomin() {
      this.zoomClick(1);
    },
    zoomout() {
      this.zoomClick(-1);
    },
    refresh() {
      this.svg.call(this.zoom.transform, d3.zoomIdentity);
    },
    showFull() {
      this.isFullscreen = !this.isFullscreen;
      var full = document.getElementById("kg_container");
      this.fullscreen(full);
    },
    fullscreen(element) {
      if (element.requestFullscreen) {
        element.requestFullscreen();
      } else if (element.mozRequestFullScreen) {
        element.mozRequestFullScreen();
      } else if (element.webkitRequestFullscreen) {
        element.webkitRequestFullscreen();
      } else if (element.msRequestFullscreen) {
        element.msRequestFullscreen();
      }
    },
    exitfullscreen() {
      this.isFullscreen = !this.isFullscreen;
      if (document.exitFullscreen) {
        document.exitFullscreen();
      } else if (document.mozCancelFullScreen) {
        document.mozCancelFullScreen();
      } else if (document.webkitExitFullscreen) {
        document.webkitExitFullscreen();
      }
    },
    btnCollapseNode() {},
    btnOpenNode() {},
    close() {}
  }
};
</script>
<style>
.svg-set-box {
  height: 46px;
  line-height: 46px;
  padding-left: 15px;
  color: #7f7f7f;
  /* background: #f7f7f7; */
  position: absolute;
  bottom: 0;
}
.ctwh-dibmr {
  display: inline-block;
}
.ss-d {
  display: inline-block;
  vertical-align: middle;
  margin-right: 10px;
  border-radius: 50%;
  background: #dedede;
}
.sd1 {
  width: 30px;
  height: 30px;
}
.sd2 {
  width: 26px;
  height: 26px;
}
.sd3 {
  width: 20px;
  height: 20px;
}
.sd4 {
  width: 16px;
  height: 16px;
}
.sd-active {
  background: #08aefc !important;
}
.toolbar {
  margin-left: 150px;
  margin-right: 15px;
  line-height: 18px;
}
ul,
li {
  list-style: none;
}
.toolbar li {
  float: left;
  width: 60px;
}
</style>
